package org.go.log;

import java.util.ArrayList;
import java.util.List;

import org.go.expcetion.GoException;

/**
 * 获取 Log 的静态工厂方法
 */
public final class LoggerFactory {
	private static LogAdapter adapter;

	private static List<LogAdapter> list = new ArrayList<LogAdapter>();

	static {
		init();
	}

	@SuppressWarnings("unchecked")
	private static LogAdapter loadLogAdapter(String... classNames) throws Exception {
		if (classNames != null) {
			try {
				for (String className : classNames) {
					Class<? extends LogAdapter> pluginClass = (Class<? extends LogAdapter>) Class.forName(className);
					list.add(pluginClass.newInstance());
					return pluginClass.newInstance();
				}
			} catch (Throwable e) {
				throw new GoException(e);
			}
		}
		return null;
	}

	/**
	 * 返回以调用者的类命名的Log,是获取Log对象最简单的方法!
	 */
	public static Log get() {
		return adapter.getLogger(Thread.currentThread().getStackTrace()[2].getClassName());
	}

	/**
	 * Get a Log by Class
	 * 
	 * @param clazz
	 *            your class
	 * @return Log
	 * @throws NullPointerException
	 *             when clazz is null
	 */
	public static Log getLog(Class<?> clazz) {
		return getLog(clazz.getName());
	}

	/**
	 * Get a Log by name
	 * 
	 * @param className
	 *            the name of Log
	 * @return Log
	 * @throws NullPointerException
	 *             when className is null, maybe it will case NPE
	 */
	public static Log getLog(String className) {
		return adapter.getLogger(className);
	}

	/**
	 * 初始化NutLog,检查全部Log的可用性,选择可用的Log适配器
	 * <p/>
	 * <b>加载本类时,该方法已经在静态构造函数中调用,用户无需主动调用.</b>
	 * <p/>
	 * <b>除非迫不得已,请不要调用本方法<b/>
	 * <p/>
	 */
	public static void init() {
		try {
			String packageName = LoggerFactory.class.getPackage().getName() + ".impl.";
			adapter = loadLogAdapter(packageName + "Slf4jLogAdapter", packageName + "Log4jAdapter", packageName + "JdkLogAdapter", packageName + "SystemLogAdapter");
			//adapter = new SimplePluginManager<LogAdapter>(packageName + "Log4jLogAdapter", packageName + "SystemLogAdapter").get();
		} catch (Throwable e) {
			//这是不应该发生的,SystemLogAdapter应该永远返回true
			//唯一的可能性是所请求的org.nutz.log.impl.SystemLogAdapter根本不存在
			//例如改了package
			e.printStackTrace();
		}
	}

	private LoggerFactory() {

	}
}
